<?php
abstract class Lesson
{
    protected $duration;
    private $costStrategy;

    public function __construct($duration, CostStrategy $costStrategy)
    {
        $this->duration = $duration;
        $this->costStrategy = $costStrategy;
    }

    public function cost()
    {
        return $this->costStrategy->cost($this);
    }

    public function chargeType(){
        return $this->costStrategy->chargeType();
    }

    public function getDuration(){
        return $this->duration;
    }


}
class Lecture extends Lesson{

}

class Seminar extends Lesson{

}

abstract class CostStrategy{
    abstract public function cost(Lesson $lesson);
    abstract public function chargeType();
}

class TimedCostStrategy extends CostStrategy{
    public function cost(Lesson $lesson)
    {
        return $lesson->getDuration() * 5;
    }

    public function chargeType()
    {
        return '按小时收费';
    }
}

class FiexdCostStrategy extends CostStrategy{
    public function cost(Lesson $lesson)
    {
        return 30;
    }

    public function chargeType()
    {
        return '固定收费';
    }
}

class RegistrationMgr{
    public function register(Lesson $lesson){
        //处理该课程省略

        //通知某人
        $notifier = Notifier::getNotifier();
        $notifier->inform('new Lesson:cost:'.$lesson->cost());
    }
}

abstract class Notifier{
    static function getNotifier(){
        //根据配置或其他逻辑获得具体的类

        if(rand(1,2) == 1){
            return new MailNotifier();
        }else{
            return new TextNotifier();
        }

    }

    abstract function inform($message);
}

class MailNotifier extends Notifier{
    function inform($message)
    {
        print '邮件通知:'.$message."\n";
    }
}

class TextNotifier extends Notifier{
    function inform($message)
    {
        print '文本通知：'.$message."\n";
    }
}

$lesson1 = new Lecture(4,new TimedCostStrategy());
$lesson2 = new Seminar(4,new FiexdCostStrategy());
$mgr = new RegistrationMgr();
$mgr->register($lesson1);
$mgr->register($lesson2);